home *** CD-ROM | disk | FTP | other *** search
- From: Kay Roemer <roemer@informatik.uni-frankfurt.de>
- Posted-Date: Tue, 21 Jun 94 15:52:04 MESZ
- Received-Date: Tue, 21 Jun 94 15:52:04 +0200
- Message-Id: <9406211352.AA10584@hera.rbi.informatik.uni-frankfurt.de>
- Subject: ser. overrun/daedlock fix
- To: mint@atari.archive.umich.edu
- Date: Tue, 21 Jun 94 15:52:04 MESZ
- Mailer: Elm [revision: 70.85]
-
- The following set of patches rel to h1 Megapatch (sorry, hadn't yet
- the time to get h2 or h3) is a better solution (at least I think) to
- the 'endless serial overrun' story, because it avoids the spl7()
- in Fselect() completely plus deadlock fix.
-
- The solution is as follows:
-
- curproc->wait_cond = condition;
- while (curproc->wait_cond == condition) {
- sleep (SELECT_Q | 0x100, condition);
- }
-
- works the same as
-
- curproc->wait_cond = condition;
- sr = spl7();
- while (curproc->wait_cond == condition) {
- sleep (SELECT_Q, condition);
- }
- spl(sr);
-
- The 0x100 tells sleep() to return without sleeping when curproc->wait_cond
- changes. This way we don't need spl7 (avoiding endless serial overruns).
- Also fixes a deadlock with checkkeys/checkbttys. They are called from
- sleep and may wakeselect() curproc. But sleep used to reset curproc->wait_cond
- to (long)wakeselect causing curproc to sleep forever.
-
- Kay.
-
- *** ../mint-110h1.orig/proc.c Mon Jun 20 23:20:20 1994
- --- proc.c Mon Jun 20 23:24:10 1994
- ***************
- *** 9,15 ****
- #include "mint.h"
- #include "xbra.h"
-
- ! static void do_wakeup_things P_((short sr));
-
- extern short proc_clock;
-
- --- 9,15 ----
- #include "mint.h"
- #include "xbra.h"
-
- ! static void do_wakeup_things P_((void));
-
- extern short proc_clock;
-
- ***************
- *** 419,426 ****
- */
-
- static void
- ! do_wakeup_things(sr)
- ! short sr;
- {
- /*
- * check for stack underflow, just in case
- --- 419,425 ----
- */
-
- static void
- ! do_wakeup_things()
- {
- /*
- * check for stack underflow, just in case
- ***************
- *** 430,438 ****
-
- p = curproc;
-
- - if ((sr & 0x700) < 0x500) {
- - /* skip all this if int level is too high */
- -
- if ( p->pid != 0 &&
- ((long)&foo) < (long)p->stack + ISTKSIZE + 512 ) {
- ALERT("stack underflow");
- --- 429,434 ----
- ***************
- *** 455,461 ****
- checkalarms();
- if (p->sigpending)
- check_sigs(); /* check for signals */
- - }
-
- if (p->slices >= 0) {
- proc_clock = TIME_SLICE; /* get a fresh time slice */
- --- 451,456 ----
- ***************
- *** 472,483 ****
- */
-
- int ARGS_ON_STACK
- ! sleep(que, cond)
- ! int que;
- long cond;
- {
- PROC *p;
- ! short sr;
- ulong onsigs = curproc->nsigs;
- extern short kintr; /* in bios.c */
- #ifndef MULTITOS
- --- 467,478 ----
- */
-
- int ARGS_ON_STACK
- ! sleep(_que, cond)
- ! int _que;
- long cond;
- {
- PROC *p;
- ! short sr, que = _que & 0xff;
- ulong onsigs = curproc->nsigs;
- extern short kintr; /* in bios.c */
- #ifndef MULTITOS
- ***************
- *** 490,509 ****
- * if there have been keyboard interrupts since our last sleep, check for
- * special keys like CTRL-ALT-Fx
- */
- !
- ! sr = spl7();
- ! if (kintr && (sr & 0x700) < 0x500) {
- ! /* can't call checkkeys if sleep was called with interrupts off -nox */
- ! spl(sr);
- (void)checkkeys();
- - sr = spl7();
- kintr = 0;
- }
-
- ! if (que == READY_Q && !sys_q[READY_Q]) {
- /* we're just going to wake up again right away! */
- spl(sr);
- ! do_wakeup_things(sr);
- return (onsigs != curproc->nsigs);
- }
-
- --- 485,507 ----
- * if there have been keyboard interrupts since our last sleep, check for
- * special keys like CTRL-ALT-Fx
- */
- ! checkbttys();
- ! if (kintr) {
- (void)checkkeys();
- kintr = 0;
- }
-
- ! sr = spl7();
- ! /*
- ! * kay: If _que & 0x100 != 0 then take curproc->wait_cond != cond as an
- ! * indicatation that the wakeup has already happend before we actually
- ! * go to sleep and return immediatly.
- ! */
- ! if ((_que & 0x100 && curproc->wait_cond != cond) ||
- ! (que == READY_Q && !sys_q[READY_Q])) {
- /* we're just going to wake up again right away! */
- spl(sr);
- ! do_wakeup_things();
- return (onsigs != curproc->nsigs);
- }
-
- ***************
- *** 559,566 ****
-
- rm_q(READY_Q, p);
-
- - spl(sr);
- -
- if (save_context(&(curproc->ctxt[CURRENT]))) {
- /*
- * restore per-process variables here
- --- 557,562 ----
- ***************
- *** 571,577 ****
- #endif
- *((void **)0x44eL) = curproc->logbase;
- #endif
- ! do_wakeup_things(sr);
- return (onsigs != curproc->nsigs);
- }
- /*
- --- 567,573 ----
- #endif
- *((void **)0x44eL) = curproc->logbase;
- #endif
- ! do_wakeup_things();
- return (onsigs != curproc->nsigs);
- }
- /*
- ***************
- *** 583,588 ****
- --- 579,590 ----
- #endif
- curproc->logbase = *((void **)0x44eL);
- #endif
- +
- + /*
- + * kay: We were at spl7 when doing the save_context(). Correct this.
- + */
- + curproc->ctxt[CURRENT].sr &= ~0x0700;
- + curproc->ctxt[CURRENT].sr |= sr & 0x0700;
- curproc->ctxt[CURRENT].regs[0] = 1;
- curproc = p;
- proc_clock = TIME_SLICE; /* fresh time */
- *** ../mint-110h1.orig/dosfile.c Mon Jun 20 23:19:54 1994
- --- dosfile.c Mon Jun 20 11:54:44 1994
- ***************
- *** 977,983 ****
- FILEPTR *f;
- PROC *p;
- TIMEOUT *t;
- - short sr;
-
- if (xfdp)
- *xfdp = 0;
- --- 977,982 ----
- ***************
- *** 1045,1051 ****
- }
-
- if (count == 0) {
- - ulong onsigs;
- /* OK, now let's set a timeout */
-
- if (timeout) {
- --- 1044,1049 ----
- ***************
- *** 1054,1079 ****
- t = 0;
- }
-
- - TRACE(("sleeping in Fselect"));
- - sr = spl7();
- -
- /* curproc->wait_cond changes when data arrives or the timeout happens */
- - onsigs = curproc->nsigs;
- while (curproc->wait_cond == (long)wakeselect) {
- - #if 0
- - /* better not call BIOS with interrupts off, especially not Bconin... :) */
- TRACE(("sleeping in Fselect"));
- ! #endif
- ! sleep(SELECT_Q, (long)wakeselect);
- ! if (curproc->sigpending) {
- ! spl(sr); /* check for signals */
- ! check_sigs();
- ! sr = spl7();
- ! }
- ! if (onsigs != curproc->nsigs)
- break;
- }
- - spl(sr);
-
- /* we can cancel the time out now (if it hasn't already happened) */
- if (t) canceltimeout(t);
- --- 1052,1072 ----
- t = 0;
- }
-
- /* curproc->wait_cond changes when data arrives or the timeout happens */
- while (curproc->wait_cond == (long)wakeselect) {
- TRACE(("sleeping in Fselect"));
- ! /*
- ! * The 0x100 tells sleep() to return without sleeping
- ! * when curproc->wait_cond changes. This way we don't
- ! * need spl7 (avoiding endless serial overruns).
- ! * Also fixes a deadlock with checkkeys/checkbttys.
- ! * They are called from sleep and may wakeselect()
- ! * curproc. But sleep used to reset curproc->wait_cond
- ! * to wakeselect causing curproc to sleep forever.
- ! */
- ! if (sleep(SELECT_Q|0x100, (long)wakeselect))
- break;
- }
-
- /* we can cancel the time out now (if it hasn't already happened) */
- if (t) canceltimeout(t);
-